######################################################################## # # Ots Hardware Mapping Language (OHML) Source File # # Hardware : Hercules DJ Control AIR DJ MIDI Hardware Controller # File Name : (Ots) Hercules DJ Control AIR.ohm # Last Updated : 19-August-2012 # OtsAV Version : 1.90.0 # # Copyright 1996-2012 Ots Corporation # # IMPORTANT NOTE: This is an original file from Ots Labs. If you wish to # make edits, it is recommended that you copy the contents of this file # to a new file first. Should you fail to do this, your changes may be # lost when Ots software updates are installed on your computer. If you # need to obtain the original version of this file at a later stage, # visit http://www.OtsAV.com # ######################################################################## # ******* Declare variables ******* # Arguments: variable name, initial value, maximum value !var[$deck_a_playing,0,1] # 1 = playing !var[$deck_b_playing,0,1] !var[$deck_a_loaded,0,1] # 1 = loaded !var[$deck_b_loaded,0,1] !var[$deck_a_jog_mode,1,1] # 0 = bending, 1 = scratching !var[$deck_b_jog_mode,1,1] !var[$deck_a_jog_button,0,1] # 1 = down (pressed) !var[$deck_b_jog_button,0,1] !var[$deck_a_frame_search,0,1] # 1 = in frame search mode !var[$deck_b_frame_search,0,1] !var[$deck_a_search_spin_counter,0,15] # for dividing (by 14) jog !var[$deck_b_search_spin_counter,0,15] # pulses when frame searching !var[$deck_a_search_rate,0,2] # frame search speed via jog !var[$deck_b_search_rate,0,2] !var[$deck_a_scratch,0,1] # 1 = currently scratching !var[$deck_b_scratch,0,1] !var[$deck_a_bend,0,21] # non-zero = currently bending !var[$deck_b_bend,0,21] !var[$deck_a_bend_down,0,1] # 1 = bend down !var[$deck_b_bend_down,0,1] !var[$deck_a_bend_up,0,1] # 1 = bend up !var[$deck_b_bend_up,0,1] !var[$deck_a_scratch_state,0,2] # tracks jog wheel state for scratching !var[$deck_b_scratch_state,0,2] !var[$deck_a_bend_state,0,1] # tracks jog wheel state for bending !var[$deck_b_bend_state,0,1] !var[$deck_a_slider_index,0,1] # 0 = tempo, 1 = pitch !var[$deck_b_slider_index,0,1] !var[$global_shift,0,1] # global shift state !var[$abm_active,0,1] # tracks abm active state !var[$playlist_down_button_count,0,7] # deck a playlist down button held counter !var[$playlist_up_button_count,0,7] # deck a playlist up button held counter !var[$deck_a_effect_pad1_down,0,1] # deck a pad1 down state !var[$deck_b_effect_pad1_down,0,1] # deck b pad1 down state !var[$deck_a_effect_pad2_down,0,1] # deck a pad2 down state !var[$deck_b_effect_pad2_down,0,1] # deck b pad2 down state !var[$deck_a_effect_pad3_down,0,1] # deck a pad3 down state !var[$deck_b_effect_pad3_down,0,1] # deck b pad3 down state !var[$deck_a_effect_pad4_down,0,1] # deck a pad4 down state !var[$deck_b_effect_pad4_down,0,1] # deck b pad4 down state !var[$deck_a_loop_pad1_down,0,1] # deck a pad1 down state !var[$deck_b_loop_pad1_down,0,1] # deck b pad1 down state !var[$deck_a_loop_pad2_down,0,1] # deck a pad2 down state !var[$deck_b_loop_pad2_down,0,1] # deck b pad2 down state !var[$deck_a_loop_pad3_down,0,1] # deck a pad3 down state !var[$deck_b_loop_pad3_down,0,1] # deck b pad3 down state !var[$deck_a_loop_pad4_down,0,1] # deck a pad4 down state !var[$deck_b_loop_pad4_down,0,1] # deck b pad4 down state !var[$deck_a_loop1_state,0,2] # deck a loop1 state !var[$deck_b_loop1_state,0,2] # deck b loop1 state !var[$deck_a_loop1_entered,0,1] # deck a loop1 entered state !var[$deck_b_loop1_entered,0,1] # deck b loop1 entered state !var[$deck_a_loop2_state,0,2] # deck a loop2 state !var[$deck_b_loop2_state,0,2] # deck b loop2 state !var[$deck_a_loop2_entered,0,1] # deck a loop2 entered state !var[$deck_b_loop2_entered,0,1] # deck b loop2 entered state # ******* Declare subroutines ******* !sub[@deck_a_try_bend] # this sub is used purely to gain !sub[@deck_b_try_bend] # use of another conditional !sub[@deck_a_try_scratch] !sub[@deck_b_try_scratch] !sub[@deck_a_try_scratch2] !sub[@deck_b_try_scratch2] !sub[@deck_a_jog_val_bend] # important to use sub for midi.velval-based !sub[@deck_b_jog_val_bend] # controls which call more than one command # in order to be efficient (CPU resources) !sub[@deck_a_jog_val_scratch] !sub[@deck_b_jog_val_scratch] !sub[@deck_a_cue_no_shift] !sub[@deck_b_cue_no_shift] !sub[@deck_a_slider_val] # new value from slider !sub[@deck_b_slider_val] !sub[@deck_a_slider_val_tempo] !sub[@deck_b_slider_val_tempo] !sub[@deck_a_slider_val_pitch] !sub[@deck_b_slider_val_pitch] !sub[@deck_a_playlist_loadnext] # load next item from playlist if !sub[@deck_b_playlist_loadnext] # deck is not currently playing !sub[@deck_a_prescratch_playing] !sub[@deck_b_prescratch_playing] !sub[@playlist_down_pressed] !sub[@playlist_down_released] !sub[@playlist_up_pressed] !sub[@playlist_up_released] !sub[@deck_a_try_loop1_press] !sub[@deck_b_try_loop1_press] !sub[@deck_a_try_loop1_press2] !sub[@deck_b_try_loop1_press2] !sub[@deck_a_loop1_state0] !sub[@deck_b_loop1_state0] !sub[@deck_a_loop1_state1] !sub[@deck_b_loop1_state1] !sub[@deck_a_try_loop2_press] !sub[@deck_b_try_loop2_press] !sub[@deck_a_try_loop2_press2] !sub[@deck_b_try_loop2_press2] !sub[@deck_a_loop2_state0] !sub[@deck_b_loop2_state0] !sub[@deck_a_loop2_state1] !sub[@deck_b_loop2_state1] !sub[@deck_a_try_length_press] !sub[@deck_b_try_length_press] !sub[@deck_a_try_length_press2] !sub[@deck_b_try_length_press2] # ******* Declare LEDs/blink assets ******* # Arguments: blink handle name, "M", midi off code, midi on code !blink[~deck_a_cue_led,M,0x90:0x11:0x00,0x90:0x11:0x7F] !blink[~deck_b_cue_led,M,0x90:0x27:0x00,0x90:0x27:0x7F] !blink[~deck_a_playpause_led,M,0x90:0x12:0x00,0x90:0x12:0x7F] !blink[~deck_b_playpause_led,M,0x90:0x28:0x00,0x90:0x28:0x7F] !blink[~deck_a_sync_led,M,0x90:0x13:0x00,0x90:0x13:0x7F] !blink[~deck_b_sync_led,M,0x90:0x29:0x00,0x90:0x29:0x7F] !blink[~deck_a_cueselect_led,M,0x90:0x14:0x00,0x90:0x14:0x7F] !blink[~deck_b_cueselect_led,M,0x90:0x2A:0x00,0x90:0x2A:0x7F] !blink[~deck_a_loop_pad1_led,M,0x90:0x09:0x00,0x90:0x09:0x7F] !blink[~deck_a_loop_pad2_led,M,0x90:0x0A:0x00,0x90:0x0A:0x7F] !blink[~deck_a_loop_pad3_led,M,0x90:0x0B:0x00,0x90:0x0B:0x7F] !blink[~deck_a_loop_pad4_led,M,0x90:0x0C:0x00,0x90:0x0C:0x7F] !blink[~deck_a_effect_pad1_led,M,0x90:0x01:0x00,0x90:0x01:0x7F] !blink[~deck_a_effect_pad2_led,M,0x90:0x02:0x00,0x90:0x02:0x7F] !blink[~deck_a_effect_pad3_led,M,0x90:0x03:0x00,0x90:0x03:0x7F] !blink[~deck_a_effect_pad4_led,M,0x90:0x04:0x00,0x90:0x04:0x7F] !blink[~deck_a_sample_pad1_led,M,0x90:0x05:0x00,0x90:0x05:0x7F] !blink[~deck_a_sample_pad2_led,M,0x90:0x06:0x00,0x90:0x06:0x7F] !blink[~deck_a_sample_pad3_led,M,0x90:0x07:0x00,0x90:0x07:0x7F] !blink[~deck_a_sample_pad4_led,M,0x90:0x08:0x00,0x90:0x08:0x7F] !blink[~deck_b_loop_pad1_led,M,0x90:0x1F:0x00,0x90:0x1F:0x7F] !blink[~deck_b_loop_pad2_led,M,0x90:0x20:0x00,0x90:0x20:0x7F] !blink[~deck_b_loop_pad3_led,M,0x90:0x21:0x00,0x90:0x21:0x7F] !blink[~deck_b_loop_pad4_led,M,0x90:0x22:0x00,0x90:0x22:0x7F] !blink[~deck_b_effect_pad1_led,M,0x90:0x17:0x00,0x90:0x17:0x7F] !blink[~deck_b_effect_pad2_led,M,0x90:0x18:0x00,0x90:0x18:0x7F] !blink[~deck_b_effect_pad3_led,M,0x90:0x19:0x00,0x90:0x19:0x7F] !blink[~deck_b_effect_pad4_led,M,0x90:0x1A:0x00,0x90:0x1A:0x7F] !blink[~deck_b_sample_pad1_led,M,0x90:0x1B:0x00,0x90:0x1B:0x7F] !blink[~deck_b_sample_pad2_led,M,0x90:0x1C:0x00,0x90:0x1C:0x7F] !blink[~deck_b_sample_pad3_led,M,0x90:0x1D:0x00,0x90:0x1D:0x7F] !blink[~deck_b_sample_pad4_led,M,0x90:0x1E:0x00,0x90:0x1E:0x7F] !blink[~deck_a_vu_beat1_led,M,0x90:0x44:0x00,0x90:0x44:0x7F] !blink[~deck_a_vu_beat2_led,M,0x90:0x45:0x00,0x90:0x45:0x7F] !blink[~deck_a_vu_beat3_led,M,0x90:0x46:0x00,0x90:0x46:0x7F] !blink[~deck_a_vu_beat4_led,M,0x90:0x47:0x00,0x90:0x47:0x7F] !blink[~deck_b_vu_beat1_led,M,0x90:0x4C:0x00,0x90:0x4C:0x7F] !blink[~deck_b_vu_beat2_led,M,0x90:0x4D:0x00,0x90:0x4D:0x7F] !blink[~deck_b_vu_beat3_led,M,0x90:0x4E:0x00,0x90:0x4E:0x7F] !blink[~deck_b_vu_beat4_led,M,0x90:0x4F:0x00,0x90:0x4F:0x7F] !blink[~files_led,M,0x90:0x35:0x00,0x90:0x35:0x7F] !blink[~folders_led,M,0x90:0x36:0x00,0x90:0x36:0x7F] !blink[~record_led,M,0x90:0x30:0x00,0x90:0x30:0x7F] !blink[~magic_led,M,0x90:0x2E:0x00,0x90:0x2E:0x7F] !blink[~scratch_led,M,0x90:0x2D:0x00,0x90:0x2D:0x7F] !blink[~front_mix_led,M,0x90:0x39:0x00,0x90:0x39:0x7F] !blink[~front_cue_led,M,0x90:0x3A:0x00,0x90:0x3A:0x7F] !blink[~front_minus_led,M,0x90:0x3B:0x00,0x90:0x3B:0x7F] !blink[~front_plus_led,M,0x90:0x3C:0x00,0x90:0x3C:0x7F] # ******* Initialisation ******* # Called by OHM subsystem at startup. # Place any code here that is important to maintain state at launch sub[@_init] { # turn off LEDs BlinkSet(~deck_a_cue_led,0) BlinkSet(~deck_b_cue_led,0) BlinkSet(~deck_a_playpause_led,0) BlinkSet(~deck_b_playpause_led,0) BlinkSet(~deck_a_sync_led,0) BlinkSet(~deck_b_sync_led,0) BlinkSet(~deck_a_cueselect_led,0) BlinkSet(~deck_b_cueselect_led,0) BlinkSet(~deck_a_loop_pad1_led,0) BlinkSet(~deck_a_loop_pad2_led,0) BlinkSet(~deck_a_loop_pad3_led,0) BlinkSet(~deck_a_loop_pad4_led,0) BlinkSet(~deck_a_effect_pad1_led,0) BlinkSet(~deck_a_effect_pad2_led,0) BlinkSet(~deck_a_effect_pad3_led,0) BlinkSet(~deck_a_effect_pad4_led,0) BlinkSet(~deck_a_sample_pad1_led,0) BlinkSet(~deck_a_sample_pad2_led,0) BlinkSet(~deck_a_sample_pad3_led,0) BlinkSet(~deck_a_sample_pad4_led,0) BlinkSet(~deck_b_loop_pad1_led,0) BlinkSet(~deck_b_loop_pad2_led,0) BlinkSet(~deck_b_loop_pad3_led,0) BlinkSet(~deck_b_loop_pad4_led,0) BlinkSet(~deck_b_effect_pad1_led,0) BlinkSet(~deck_b_effect_pad2_led,0) BlinkSet(~deck_b_effect_pad3_led,0) BlinkSet(~deck_b_effect_pad4_led,0) BlinkSet(~deck_b_sample_pad1_led,0) BlinkSet(~deck_b_sample_pad2_led,0) BlinkSet(~deck_b_sample_pad3_led,0) BlinkSet(~deck_b_sample_pad4_led,0) BlinkSet(~deck_a_vu_beat1_led,0) BlinkSet(~deck_a_vu_beat2_led,0) BlinkSet(~deck_a_vu_beat3_led,0) BlinkSet(~deck_a_vu_beat4_led,0) BlinkSet(~deck_b_vu_beat1_led,0) BlinkSet(~deck_b_vu_beat2_led,0) BlinkSet(~deck_b_vu_beat3_led,0) BlinkSet(~deck_b_vu_beat4_led,0) BlinkSet(~files_led,0) BlinkSet(~folders_led,0) BlinkSet(~record_led,0) BlinkSet(~magic_led,0) BlinkSet(~scratch_led,0) BlinkSet(~front_mix_led,0) BlinkSet(~front_cue_led,0) BlinkSet(~front_minus_led,0) BlinkSet(~front_plus_led,0) # turn on tempo and scratch jog mode leds which default to on BlinkSet(~scratch_led,1) BlinkSet(~deck_a_effect_pad4_led,1) BlinkSet(~deck_b_effect_pad4_led,1) # get current OtsAV state avStateRequest() # will generate appropriate Load, Play, etc events avPlaylistNav(E) # enables playlist navigation } # ******* Respond to OtsAV/other events ******* ######################################################## ####### Deck A: Load/Cue/Play-Pause/Frame Search/etc av[Load,A,E] { # Deck A Load (entered Loaded state) VarSet($deck_a_loaded,1) # save state for our own use BlinkSet(~deck_a_playpause_led,3) # medium blink } av[Load,A,D] { # Deck A Eject (left Loaded state) VarSet($deck_a_loaded,0) # clear state BlinkSet(~deck_a_playpause_led,0) # off } av[Play,A,E] { # Deck A Play (entered Playing state) VarSet($deck_a_playing,1) # save state for our own use BlinkSet(~deck_a_playpause_led,1) # on } av[Play,A,D] { # Deck A Stop (left Playing state) VarSet($deck_a_playing,0) # clear state BlinkSet(~deck_a_playpause_led,3) # medium blink } av[Cued,A,E] { # Deck A entered Cued state BlinkSet(~deck_a_cue_led,1) # on } av[Cued,A,D] { # Deck A left Cued state BlinkSet(~deck_a_cue_led,0) # off } av[PreMix,A,E] { # Deck A entered Pre-mix state BlinkSet(~deck_a_playpause_led,4) # fast blink } av[PreMix,A,D] { # Deck A left Pre-mix state BlinkSet(~deck_a_playpause_led,3) # medium blink } av[FrameSearch,A,E] { # Deck A entered Frame Search mode VarSet($deck_a_frame_search,1) # save state for our own use VarSet($deck_a_search_spin_counter,7) BlinkSet(~deck_a_cue_led,4) # fast blink } av[FrameSearch,A,D] { # Deck A left Frame Search mode VarSet($deck_a_frame_search,0) # clear state BlinkSet(~deck_a_cue_led,0) # off } ####### Deck B: Load/Cue/Play-Pause/Frame Search/etc av[Load,B,E] { # Deck B Load (entered Loaded state) VarSet($deck_b_loaded,1) # save state for our own use BlinkSet(~deck_b_playpause_led,3) # medium blink } av[Load,B,D] { # Deck B Eject (left Loaded state) VarSet($deck_b_loaded,0) # clear state BlinkSet(~deck_b_playpause_led,0) # off } av[Play,B,E] { # Deck B Play (entered Playing state) VarSet($deck_b_playing,1) # save state for our own use BlinkSet(~deck_b_playpause_led,1) # on } av[Play,B,D] { # Deck B Stop (left Playing state) VarSet($deck_b_playing,0) # clear state BlinkSet(~deck_b_playpause_led,3) # medium blink } av[Cued,B,E] { # Deck B entered Cued state BlinkSet(~deck_b_cue_led,1) # on } av[Cued,B,D] { # Deck B left Cued state BlinkSet(~deck_b_cue_led,0) # off } av[PreMix,B,E] { # Deck B entered Pre-mix state BlinkSet(~deck_b_playpause_led,4) # fast blink } av[PreMix,B,D] { # Deck B left Pre-mix state BlinkSet(~deck_b_playpause_led,3) # medium blink } av[FrameSearch,B,E] { # Deck B entered Frame Search mode VarSet($deck_b_frame_search,1) # save state for our own use VarSet($deck_b_search_spin_counter,7) BlinkSet(~deck_b_cue_led,4) # fast blink } av[FrameSearch,B,D] { # Deck B left Frame Search mode VarSet($deck_b_frame_search,0) # clear state BlinkSet(~deck_b_cue_led,0) # off } ######################################################## ####### Deck A: Primary transport controls midi.trigger[0x90:0x12:0x7F] { # Deck A Play/Pause button down ($global_shift=0) avPlayPause(A,E) ($global_shift=1) avPlay(A) } midi.trigger[0x90:0x12:0x00] { # Deck A Play/Pause button up avPlayPause(A,D) } midi.trigger[0x90:0x11:0x7F] { # Deck A Cue button down ($global_shift=0) SubCall(@deck_a_cue_no_shift) ($global_shift=1) avCueSet(A) } sub[@deck_a_cue_no_shift] { # Deck A Cue button down without shift ($deck_a_scratch=0) avCue(A,E) ($deck_a_scratch=1) avCueSet(A) } midi.trigger[0x90:0x11:0x00] { # Deck A Cue button up avCue(A,D) } midi.trigger[0x90:0x0F:0x7F] { # Deck A Frame Search (back) button down avFrameSearch(A,-1) } midi.trigger[0x90:0x10:0x7F] { # Deck A Frame Search (forward) button down avFrameSearch(A,+1) } midi.relval[0xB0:0x30,0x40,0xC0,0x80] ($deck_a_frame_search=1) VarDec($deck_a_search_spin_counter) midi.relval[0xB0:0x30,0x00,0xC0,0x00] ($deck_a_frame_search=1) VarInc($deck_a_search_spin_counter) midi.relval[0xB0:0x32,0x40,0xC0,0x80] ($deck_a_frame_search=1) VarDec($deck_a_search_spin_counter) midi.relval[0xB0:0x32,0x00,0xC0,0x00] ($deck_a_frame_search=1) VarInc($deck_a_search_spin_counter) var.set[$deck_a_search_spin_counter=0] { ($deck_a_search_rate=0) avFrameSearch(A,-1) ($deck_a_search_rate=1) avFrameSearch(A,-5) ($deck_a_search_rate=2) avFrameSearch(A,-20) VarInc($deck_a_search_rate) VarSet($deck_a_search_spin_counter,14) } var.set[$deck_a_search_spin_counter=15] { ($deck_a_search_rate=0) avFrameSearch(A,+1) ($deck_a_search_rate=1) avFrameSearch(A,+5) ($deck_a_search_rate=2) avFrameSearch(A,+20) VarInc($deck_a_search_rate) VarSet($deck_a_search_spin_counter,1) } timer.tick VarDec($deck_a_search_rate) ####### Deck B: Primary transport controls midi.trigger[0x90:0x28:0x7F] { # Deck B Play/Pause button down ($global_shift=0) avPlayPause(B,E) ($global_shift=1) avPlay(B) } midi.trigger[0x90:0x28:0x00] { # Deck B Play/Pause button up avPlayPause(B,D) } midi.trigger[0x90:0x27:0x7F] { # Deck B Cue button down ($global_shift=0) SubCall(@deck_b_cue_no_shift) ($global_shift=1) avCueSet(B) } sub[@deck_b_cue_no_shift] { # Deck B Cue button down without shift ($deck_b_scratch=0) avCue(B,E) ($deck_b_scratch=1) avCueSet(B) } midi.trigger[0x90:0x27:0x00] { # Deck B Cue button up avCue(B,D) } midi.trigger[0x90:0x25:0x7F] { # Deck B Frame Search (back) button down avFrameSearch(B,-1) } midi.trigger[0x90:0x26:0x7F] { # Deck B Frame Search (forward) button down avFrameSearch(B,+1) } midi.relval[0xB0:0x31,0x40,0xC0,0x80] ($deck_b_frame_search=1) VarDec($deck_b_search_spin_counter) midi.relval[0xB0:0x31,0x00,0xC0,0x00] ($deck_b_frame_search=1) VarInc($deck_b_search_spin_counter) midi.relval[0xB0:0x33,0x40,0xC0,0x80] ($deck_b_frame_search=1) VarDec($deck_b_search_spin_counter) midi.relval[0xB0:0x33,0x00,0xC0,0x00] ($deck_b_frame_search=1) VarInc($deck_b_search_spin_counter) var.set[$deck_b_search_spin_counter=0] { ($deck_b_search_rate=0) avFrameSearch(B,-1) ($deck_b_search_rate=1) avFrameSearch(B,-5) ($deck_b_search_rate=2) avFrameSearch(B,-20) VarInc($deck_b_search_rate) VarSet($deck_b_search_spin_counter,14) } var.set[$deck_b_search_spin_counter=15] { ($deck_b_search_rate=0) avFrameSearch(B,+1) ($deck_b_search_rate=1) avFrameSearch(B,+5) ($deck_b_search_rate=2) avFrameSearch(B,+20) VarInc($deck_b_search_rate) VarSet($deck_b_search_spin_counter,1) } timer.tick VarDec($deck_b_search_rate) ######################################################## ####### Deck A: Jog mode/Bending/Scratching var.set[$deck_a_jog_mode=0] { ($deck_a_scratch=1) VarSet($deck_a_scratch,0) # cancel scratching if enabled } var.set[$deck_a_jog_mode=1] { ($deck_a_bend=1) VarSet($deck_a_bend,0) # cancel bending if enabled } var.set[$deck_a_playing=0] { # Deck A Stop (left Playing state) ($deck_a_bend=1) VarSet($deck_a_bend,0) # cancel bending if enabled ($deck_a_bend_down=1) VarSet($deck_a_bend_down,0) # cancel bend down if enabled ($deck_a_bend_up=1) VarSet($deck_a_bend_up,0) # cancel bend up if enabled ($deck_a_scratch=1) VarSet($deck_a_scratch,0) # cancel scratching if enabled } var.set[$deck_a_frame_search=1] { # Deck A entered Frame Search mode ($deck_a_bend=1) VarSet($deck_a_bend,0) # cancel bending if enabled ($deck_a_scratch=1) VarSet($deck_a_scratch,0) # cancel scratching if enabled } midi.trigger[0x90:0x16:0x7F] { # Deck A Jog button down VarSet($deck_a_jog_button,1) } var.set[$deck_a_jog_button=1] { ($deck_a_jog_mode=1) SubCall(@deck_a_try_scratch) } sub[@deck_a_try_scratch] ($deck_a_playing=1) SubCall(@deck_a_try_scratch2) sub[@deck_a_try_scratch2] { ($deck_a_frame_search=0) VarSet($deck_a_scratch,1) } midi.trigger[0x90:0x16:0x00] { # Deck A Jog button up VarSet($deck_a_jog_button,0) } var.set[$deck_a_jog_button=0] { ($deck_a_scratch_state!=1) VarSet($deck_a_scratch,0) # cancel scratching if jog inactive } var.set[$deck_a_scratch=1] { avScratch(A,E,0.0) BlinkSet(~deck_a_cue_led,4) # fast blink } var.set[$deck_a_scratch=0] { avScratch(A,D,0.0) BlinkSet(~deck_a_cue_led,0) } sub[@deck_a_try_bend] ($deck_a_frame_search=0) VarSet($deck_a_bend,1) var.set[$deck_a_bend=1] { ($deck_a_bend_down=1) VarSet($deck_a_bend_down,0) # cancel bend down if enabled ($deck_a_bend_up=1) VarSet($deck_a_bend_up,0) # cancel bend up if enabled avBend(A,E,0.0) } var.set[$deck_a_bend=0] { avBend(A,D,0.0) } midi.velval[R,0xB0:0x30,0x80,0x00,0,6.7,0.1,$deck_a_bend_state,0,0xFF:0xFD] ($deck_a_jog_mode=0) SubCall(@deck_a_jog_val_bend) midi.velval[R,0xB0:0x30,0x80,0x00,0,2.8,0.3,$deck_a_scratch_state,0,0xFF:0xFD] ($deck_a_jog_mode=1) SubCall(@deck_a_jog_val_scratch) sub[@deck_a_jog_val_bend] { # new value from jog wheel ($deck_a_bend=1) avBendSet(A,_) } var.set[$deck_a_bend_state!=0] { # jog wheel active in bending mode ($deck_a_playing=1) SubCall(@deck_a_try_bend) } var.set[$deck_a_bend_state=0] { # jog wheel inactive in bending mode VarSet($deck_a_bend,0) # cancel bending } sub[@deck_a_jog_val_scratch] { # new value from jog wheel ($deck_a_scratch=1) avScratchSet(A,_) } var.set[$deck_a_scratch_state!=1] { # jog wheel inactive in scratching mode ($deck_a_jog_button=0) VarSet($deck_a_scratch,0) # cancel scratching if jog button not down } midi.trigger[0x90:0x0D:0x7F] ($deck_a_playing=1) VarSet($deck_a_bend_down,1) midi.trigger[0x90:0x0D:0x00] ($deck_a_bend_down=1) VarSet($deck_a_bend_down,0) midi.trigger[0x90:0x0E:0x7F] ($deck_a_playing=1) VarSet($deck_a_bend_up,1) midi.trigger[0x90:0x0E:0x00] ($deck_a_bend_up=1) VarSet($deck_a_bend_up,0) var.set[$deck_a_bend_down=1] { ($deck_a_bend=1) VarSet($deck_a_bend,0) # cancel bending if enabled ($deck_a_bend_up=1) VarSet($deck_a_bend_up,0) # cancel bend up if enabled avBend(A,E,-0.4) # bend down at 4% } var.set[$deck_a_bend_down=0] { avBend(A,D,0.0) # cancel bend down } var.set[$deck_a_bend_up=1] { ($deck_a_bend=1) VarSet($deck_a_bend,0) # cancel bending if enabled ($deck_a_bend_down=1) VarSet($deck_a_bend_down,0) # cancel bend down if enabled avBend(A,E,+0.4) # bend up at 4% } var.set[$deck_a_bend_up=0] { avBend(A,D,0.0) # cancel bend up } ####### Deck B: Jog mode/Bending/Scratching var.set[$deck_b_jog_mode=0] { ($deck_b_scratch=1) VarSet($deck_b_scratch,0) # cancel scratching if enabled } var.set[$deck_b_jog_mode=1] { ($deck_b_bend=1) VarSet($deck_b_bend,0) # cancel bending if enabled } var.set[$deck_b_playing=0] { # Deck B Stop (left Playing state) ($deck_b_bend=1) VarSet($deck_b_bend,0) # cancel bending if enabled ($deck_b_bend_down=1) VarSet($deck_b_bend_down,0) # cancel bend down if enabled ($deck_b_bend_up=1) VarSet($deck_b_bend_up,0) # cancel bend up if enabled ($deck_b_scratch=1) VarSet($deck_b_scratch,0) # cancel scratching if enabled } var.set[$deck_b_frame_search=1] { # Deck B entered Frame Search mode ($deck_b_bend=1) VarSet($deck_b_bend,0) # cancel bending if enabled ($deck_b_scratch=1) VarSet($deck_b_scratch,0) # cancel scratching if enabled } midi.trigger[0x90:0x2C:0x7F] { # Deck B Jog button down VarSet($deck_b_jog_button,1) } var.set[$deck_b_jog_button=1] { ($deck_b_jog_mode=1) SubCall(@deck_b_try_scratch) } sub[@deck_b_try_scratch] ($deck_b_playing=1) SubCall(@deck_b_try_scratch2) sub[@deck_b_try_scratch2] { ($deck_b_frame_search=0) VarSet($deck_b_scratch,1) } midi.trigger[0x90:0x2C:0x00] { # Deck B Jog button up VarSet($deck_b_jog_button,0) } var.set[$deck_b_jog_button=0] { ($deck_b_scratch_state!=1) VarSet($deck_b_scratch,0) # cancel scratching if jog inactive } var.set[$deck_b_scratch=1] { avScratch(B,E,0.0) BlinkSet(~deck_b_cue_led,4) # fast blink } var.set[$deck_b_scratch=0] { avScratch(B,D,0.0) BlinkSet(~deck_b_cue_led,0) } sub[@deck_b_try_bend] ($deck_b_frame_search=0) VarSet($deck_b_bend,1) var.set[$deck_b_bend=1] { ($deck_b_bend_down=1) VarSet($deck_b_bend_down,0) # cancel bend down if enabled ($deck_b_bend_up=1) VarSet($deck_b_bend_up,0) # cancel bend up if enabled avBend(B,E,0.0) } var.set[$deck_b_bend=0] { avBend(B,D,0.0) } midi.velval[R,0xB0:0x31,0x80,0x00,0,6.7,0.1,$deck_b_bend_state,0,0xFF:0xFD] ($deck_b_jog_mode=0) SubCall(@deck_b_jog_val_bend) midi.velval[R,0xB0:0x31,0x80,0x00,0,2.8,0.3,$deck_b_scratch_state,0,0xFF:0xFD] ($deck_b_jog_mode=1) SubCall(@deck_b_jog_val_scratch) sub[@deck_b_jog_val_bend] { # new value from jog wheel ($deck_b_bend=1) avBendSet(B,_) } var.set[$deck_b_bend_state!=0] { # jog wheel active in bending mode ($deck_b_playing=1) SubCall(@deck_b_try_bend) } var.set[$deck_b_bend_state=0] { # jog wheel inactive in bending mode VarSet($deck_b_bend,0) # cancel bending } sub[@deck_b_jog_val_scratch] { # new value from jog wheel ($deck_b_scratch=1) avScratchSet(B,_) } var.set[$deck_b_scratch_state!=1] { # jog wheel inactive in scratching mode ($deck_b_jog_button=0) VarSet($deck_b_scratch,0) # cancel scratching if jog button not down } midi.trigger[0x90:0x23:0x7F] ($deck_b_playing=1) VarSet($deck_b_bend_down,1) midi.trigger[0x90:0x23:0x00] ($deck_b_bend_down=1) VarSet($deck_b_bend_down,0) midi.trigger[0x90:0x24:0x7F] ($deck_b_playing=1) VarSet($deck_b_bend_up,1) midi.trigger[0x90:0x24:0x00] ($deck_b_bend_up=1) VarSet($deck_b_bend_up,0) var.set[$deck_b_bend_down=1] { ($deck_b_bend=1) VarSet($deck_b_bend,0) # cancel bending if enabled ($deck_b_bend_up=1) VarSet($deck_b_bend_up,0) # cancel bend up if enabled avBend(B,E,-0.4) # bend down at 4% } var.set[$deck_b_bend_down=0] { avBend(B,D,0.0) # cancel bend down } var.set[$deck_b_bend_up=1] { ($deck_b_bend=1) VarSet($deck_b_bend,0) # cancel bending if enabled ($deck_b_bend_down=1) VarSet($deck_b_bend_down,0) # cancel bend down if enabled avBend(B,E,+0.4) # bend up at 4% } var.set[$deck_b_bend_up=0] { avBend(B,D,0.0) # cancel bend up } ######################################################## ####### Deck A: Bass/Mid/High EQ knobs midi.absval[S,0xB0:0x39,0x00,0x3F,0x7F] { # Deck A - Low EQ knob capture avEQGainBass(A,_) # Set Deck A Bass Level } midi.absval[S,0xB0:0x38,0x00,0x3F,0x7F] { # Deck A - Mid EQ knob capture avEQGainMid(A,_) # Set Deck A Mid Level } midi.absval[S,0xB0:0x37,0x00,0x3F,0x7F] { # Deck A - High EQ knob capture avEQGainHigh(A,_) # Set Deck A High Level } ####### Deck B: Bass/Mid/High EQ knobs midi.absval[S,0xB0:0x3E,0x00,0x3F,0x7F] { # Deck B - Low EQ knob capture avEQGainBass(B,_) # Set Deck B Bass Level } midi.absval[S,0xB0:0x3D,0x00,0x3D,0x7F] { # Deck B - Mid EQ knob capture avEQGainMid(B,_) # Set Deck B Mid Level } midi.absval[S,0xB0:0x3C,0x00,0x3F,0x7F] { # Deck B - High EQ knob capture avEQGainHigh(B,_) # Set Deck B High Level } ######################################################## ####### Deck A: Bass/Mid/High cut midi.trigger[0x90:0x01:0x20,0xFF:0xFF:0x20] { # Deck A - Cut Bass pad down (MIDI codes type 1) (midi.trigger with mask to capture upper 3/4 range) ($deck_a_effect_pad1_down=0) avEQCutBass(A,T) # Toggle Deck A Bass Cut (only toggle if pad not been down already) VarSet($deck_a_effect_pad1_down,1) } midi.trigger[0xA0:0x01:0x20,0xFF:0xFF:0x20] { # Deck A - Cut Bass pad down (MIDI codes type 2) (midi.trigger with mask to capture upper 3/4 range) ($deck_a_effect_pad1_down=0) avEQCutBass(A,T) # Toggle Deck A Bass Cut (only toggle if pad not been down already) VarSet($deck_a_effect_pad1_down,1) } midi.trigger[0x90:0x01:0x00] { # Deck A - Cut Bass pad up VarSet($deck_a_effect_pad1_down,0) } midi.trigger[0x90:0x02:0x20,0xFF:0xFF:0x20] { # Deck A - Cut Mid pad down (MIDI codes type 1) (midi.trigger with mask to capture upper 3/4 range) ($deck_a_effect_pad2_down=0) avEQCutMid(A,T) # Toggle Deck A Mid Cut (only toggle if pad not been down already) VarSet($deck_a_effect_pad2_down,1) } midi.trigger[0xA0:0x02:0x20,0xFF:0xFF:0x20] { # Deck A - Cut Mid pad down (MIDI codes type 2) (midi.trigger with mask to capture upper 3/4 range) ($deck_a_effect_pad2_down=0) avEQCutMid(A,T) # Toggle Deck A Mid Cut (only toggle if pad not been down already) VarSet($deck_a_effect_pad2_down,1) } midi.trigger[0x90:0x02:0x00] { # Deck A - Cut Mid pad up VarSet($deck_a_effect_pad2_down,0) } midi.trigger[0x90:0x03:0x20,0xFF:0xFF:0x20] { # Deck A - Cut High pad down (MIDI codes type 1) (midi.trigger with mask to capture upper 3/4 range) ($deck_a_effect_pad3_down=0) avEQCutHigh(A,T) # Toggle Deck A High Cut (only toggle if pad not been down already) VarSet($deck_a_effect_pad3_down,1) } midi.trigger[0xA0:0x03:0x20,0xFF:0xFF:0x20] { # Deck A - Cut High pad down (MIDI codes type 2) (midi.trigger with mask to capture upper 3/4 range) ($deck_a_effect_pad3_down=0) avEQCutHigh(A,T) # Toggle Deck A High Cut (only toggle if pad not been down already) VarSet($deck_a_effect_pad3_down,1) } midi.trigger[0x90:0x03:0x00] { # Deck A - Cut High pad up VarSet($deck_a_effect_pad3_down,0) } av[EQCutBass,A,E] { # Deck A Bass Cut enabled BlinkSet(~deck_a_effect_pad1_led,1) } av[EQCutBass,A,D] { # Deck A Bass Cut disabled BlinkSet(~deck_a_effect_pad1_led,0) } av[EQCutMid,A,E] { # Deck A Mid Cut enabled BlinkSet(~deck_a_effect_pad2_led,1) } av[EQCutMid,A,D] { # Deck A Mid Cut disabled BlinkSet(~deck_a_effect_pad2_led,0) } av[EQCutHigh,A,E] { # Deck A High Cut enabled BlinkSet(~deck_a_effect_pad3_led,1) } av[EQCutHigh,A,D] { # Deck A High Cut disabled BlinkSet(~deck_a_effect_pad3_led,0) } ####### Deck B: Bass/Mid/High cut midi.trigger[0x90:0x17:0x20,0xFF:0xFF:0x20] { # Deck B - Cut Bass pad down (MIDI codes type 1) (midi.trigger with mask to capture upper 3/4 range) ($deck_b_effect_pad1_down=0) avEQCutBass(B,T) # Toggle Deck B Bass Cut (only toggle if pad not been down already) VarSet($deck_b_effect_pad1_down,1) } midi.trigger[0xA0:0x17:0x20,0xFF:0xFF:0x20] { # Deck B - Cut Bass pad down (MIDI codes type 2) (midi.trigger with mask to capture upper 3/4 range) ($deck_b_effect_pad1_down=0) avEQCutBass(B,T) # Toggle Deck B Bass Cut (only toggle if pad not been down already) VarSet($deck_b_effect_pad1_down,1) } midi.trigger[0x90:0x17:0x00] { # Deck B - Cut Bass pad up VarSet($deck_b_effect_pad1_down,0) } midi.trigger[0x90:0x18:0x20,0xFF:0xFF:0x20] { # Deck B - Cut Mid pad down (MIDI codes type 1) (midi.trigger with mask to capture upper 3/4 range) ($deck_b_effect_pad2_down=0) avEQCutMid(B,T) # Toggle Deck B Mid Cut (only toggle if pad not been down already) VarSet($deck_b_effect_pad2_down,1) } midi.trigger[0xA0:0x18:0x20,0xFF:0xFF:0x20] { # Deck B - Cut Mid pad down (MIDI codes type 2) (midi.trigger with mask to capture upper 3/4 range) ($deck_b_effect_pad2_down=0) avEQCutMid(B,T) # Toggle Deck B Mid Cut (only toggle if pad not been down already) VarSet($deck_b_effect_pad2_down,1) } midi.trigger[0x90:0x18:0x00] { # Deck B - Cut Mid pad up VarSet($deck_b_effect_pad2_down,0) } midi.trigger[0x90:0x19:0x20,0xFF:0xFF:0x20] { # Deck B - Cut High pad down (MIDI codes type 1) (midi.trigger with mask to capture upper 3/4 range) ($deck_b_effect_pad3_down=0) avEQCutHigh(B,T) # Toggle Deck B High Cut (only toggle if pad not been down already) VarSet($deck_b_effect_pad3_down,1) } midi.trigger[0xA0:0x19:0x20,0xFF:0xFF:0x20] { # Deck B - Cut High pad down (MIDI codes type 2) (midi.trigger with mask to capture upper 3/4 range) ($deck_b_effect_pad3_down=0) avEQCutHigh(B,T) # Toggle Deck B High Cut (only toggle if pad not been down already) VarSet($deck_b_effect_pad3_down,1) } midi.trigger[0x90:0x19:0x00] { # Deck B - Cut High pad up VarSet($deck_b_effect_pad3_down,0) } av[EQCutBass,B,E] { # Deck B Bass Cut enabled BlinkSet(~deck_b_effect_pad1_led,1) } av[EQCutBass,B,D] { # Deck B Bass Cut disabled BlinkSet(~deck_b_effect_pad1_led,0) } av[EQCutMid,B,E] { # Deck B Mid Cut enabled BlinkSet(~deck_b_effect_pad2_led,1) } av[EQCutMid,B,D] { # Deck B Mid Cut disabled BlinkSet(~deck_b_effect_pad2_led,0) } av[EQCutHigh,B,E] { # Deck B High Cut enabled BlinkSet(~deck_b_effect_pad3_led,1) } av[EQCutHigh,B,D] { # Deck B High Cut disabled BlinkSet(~deck_b_effect_pad3_led,0) } ######################################################## ####### Crossfader midi.absval[S,0xB0:0x3A,0x00,0x3F,0x7F] { avXFaderSet(_) # normal sync logic } ######################################################## ####### ABM Active av[ABMActive,E] { VarSet($abm_active,1) } av[ABMActive,D] { VarSet($abm_active,0) } var.set[$abm_active=1] { BlinkSet(~deck_a_sync_led,4) # fast blink BlinkSet(~deck_b_sync_led,12) # inverse fast blink BlinkSet(~deck_a_vu_beat1_led,4) # fast blink BlinkSet(~deck_a_vu_beat2_led,12) # inverse fast blink BlinkSet(~deck_a_vu_beat3_led,4) # fast blink BlinkSet(~deck_a_vu_beat4_led,12) # inverse fast blink BlinkSet(~deck_b_vu_beat1_led,12) # inverse fast blink BlinkSet(~deck_b_vu_beat2_led,4) # fast blink BlinkSet(~deck_b_vu_beat3_led,12) # inverse fast blink BlinkSet(~deck_b_vu_beat4_led,4) # fast blink } var.set[$abm_active=0] { BlinkSet(~deck_a_sync_led,0) # back to off BlinkSet(~deck_b_sync_led,0) BlinkSet(~deck_a_vu_beat1_led,0) BlinkSet(~deck_a_vu_beat2_led,0) BlinkSet(~deck_a_vu_beat3_led,0) BlinkSet(~deck_a_vu_beat4_led,0) BlinkSet(~deck_b_vu_beat1_led,0) BlinkSet(~deck_b_vu_beat2_led,0) BlinkSet(~deck_b_vu_beat3_led,0) BlinkSet(~deck_b_vu_beat4_led,0) } av[ABMBeat.1] { ($abm_active=1) BlinkSet(~deck_a_vu_beat1_led,1) ($abm_active=1) BlinkSet(~deck_b_vu_beat1_led,1) ($abm_active=1) BlinkSet(~deck_a_vu_beat4_led,0) ($abm_active=1) BlinkSet(~deck_b_vu_beat4_led,0) } av[ABMBeat.2] { ($abm_active=1) BlinkSet(~deck_a_vu_beat2_led,1) ($abm_active=1) BlinkSet(~deck_b_vu_beat2_led,1) ($abm_active=1) BlinkSet(~deck_a_vu_beat1_led,0) ($abm_active=1) BlinkSet(~deck_b_vu_beat1_led,0) } av[ABMBeat.3] { ($abm_active=1) BlinkSet(~deck_a_vu_beat3_led,1) ($abm_active=1) BlinkSet(~deck_b_vu_beat3_led,1) ($abm_active=1) BlinkSet(~deck_a_vu_beat2_led,0) ($abm_active=1) BlinkSet(~deck_b_vu_beat2_led,0) } av[ABMBeat.4] { ($abm_active=1) BlinkSet(~deck_a_vu_beat4_led,1) ($abm_active=1) BlinkSet(~deck_b_vu_beat4_led,1) ($abm_active=1) BlinkSet(~deck_a_vu_beat3_led,0) ($abm_active=1) BlinkSet(~deck_b_vu_beat3_led,0) } ######################################################## ####### Global Shift state midi.trigger[0x90:0x30:0x7F] VarSet($global_shift,1) midi.trigger[0x90:0x30:0x00] VarSet($global_shift,0) ######################################################## ####### Mix Now - Magic Button midi.trigger[0x90:0x2E:0x7F] avNext() # Mix now ######################################################## ####### Cue A and Cue B button functionality midi.trigger[0x90:0x14:0x7F] { avMixer.Cue(A,T) # Toggle Deck A Mixer Cue Button } midi.trigger[0x90:0x2A:0x7F] { avMixer.Cue(B,T) # Toggle Deck B Mixer Cue Button } av[Mixer.Cue,A,E] { BlinkSet(~deck_a_cueselect_led,1) } av[Mixer.Cue,B,E] { BlinkSet(~deck_b_cueselect_led,1) } av[Mixer.Cue,A,D] { BlinkSet(~deck_a_cueselect_led,0) } av[Mixer.Cue,B,D] { BlinkSet(~deck_b_cueselect_led,0) } ######################################################## ####### Sync A and Sync B button functionality midi.trigger[0x90:0x13:0x7F] { # Sync A button down ($deck_a_slider_index=0) avBPMMatch.Tempo(A) ($deck_a_slider_index=1) avBPMMatch.Pitch(A) } midi.trigger[0x90:0x29:0x7F] { # Sync B button down ($deck_b_slider_index=0) avBPMMatch.Tempo(B) ($deck_b_slider_index=1) avBPMMatch.Pitch(B) } ######################################################## ####### Scratch/Bend Jog Mode midi.trigger[0x90:0x2D:0x7F] { # Scratch button down VarIncWrap($deck_a_jog_mode) # Change between Scratch/Bend mode VarIncWrap($deck_b_jog_mode) # Change between Scratch/Bend mode ($deck_a_jog_mode=0) BlinkSet(~scratch_led,0) # Turn off scratch led (only one scratch led and button on this controller) ($deck_a_jog_mode=1) BlinkSet(~scratch_led,1) # Turn on scratch led (only one scratch led and button on this controller) } ######################################################## ####### Mixer Level Sliders midi.absval[S,0xB0:0x36,0x00,0x64,0x7F] { ($global_shift=0) avLevelSet(A,_) # Sets Deck A level on OtsAV Mixer ($global_shift=1) avLevelSet(A,_,F0|F4) # bypass sync logic and snap value } midi.absval[S,0xB0:0x3B,0x00,0x64,0x7F] { ($global_shift=0) avLevelSet(B,_) # Sets Deck B level on OtsAV Mixer ($global_shift=1) avLevelSet(B,_,F0|F4) # bypass sync logic and snap value } ######################################################## ####### Tempo/Pitch Slider mode (tempo or pitch) midi.trigger[0x90:0x04:0x20,0xFF:0xFF:0x20] { # slider mode A pad down (MIDI codes type 1) (midi.trigger with mask to capture upper 3/4 range) ($deck_a_effect_pad4_down=0) VarIncWrap($deck_a_slider_index) # only toggle if pad not been down already VarSet($deck_a_effect_pad4_down,1) } midi.trigger[0xA0:0x04:0x20,0xFF:0xFF:0x20] { # slider mode A pad down (MIDI codes type 2) (midi.trigger with mask to capture upper 3/4 range) ($deck_a_effect_pad4_down=0) VarIncWrap($deck_a_slider_index) # only toggle if pad not been down already VarSet($deck_a_effect_pad4_down,1) } midi.trigger[0x90:0x04:0x00] { # slider mode A pad up VarSet($deck_a_effect_pad4_down,0) } midi.trigger[0x90:0x1A:0x20,0xFF:0xFF:0x20] { # slider mode B pad down (MIDI codes type 1) (midi.trigger with mask to capture upper 3/4 range) ($deck_b_effect_pad4_down=0) VarIncWrap($deck_b_slider_index) # only toggle if pad not been down already VarSet($deck_b_effect_pad4_down,1) } midi.trigger[0xA0:0x1A:0x20,0xFF:0xFF:0x20] { # slider mode B pad down (MIDI codes type 2) (midi.trigger with mask to capture upper 3/4 range) ($deck_b_effect_pad4_down=0) VarIncWrap($deck_b_slider_index) # only toggle if pad not been down already VarSet($deck_b_effect_pad4_down,1) } midi.trigger[0x90:0x1A:0x00] { # slider mode B pad up VarSet($deck_b_effect_pad4_down,0) } ######################################################## ####### Deck A: Slider midi.absval[S,0xB0:0x34,0x7F,0x40,0x00] SubCall(@deck_a_slider_val) sub[@deck_a_slider_val] { # new value from slider ($deck_a_slider_index=0) SubCall(@deck_a_slider_val_tempo) ($deck_a_slider_index=1) SubCall(@deck_a_slider_val_pitch) } sub[@deck_a_slider_val_tempo] { # slider pos -- tempo ($global_shift=0) avTempoSet(A,_) # normal sync logic ($global_shift=1) avTempoSet(A,_,F1) # force synced state } sub[@deck_a_slider_val_pitch] { # slider pos -- pitch ($global_shift=0) avPitchSet(A,_) # normal sync logic ($global_shift=1) avPitchSet(A,_,F1) # force synced state } var.set[$deck_a_slider_index=0] { avTempoSet(A,0.0,F2|F7) # init sync with last pitch slider position BlinkSet(~deck_a_effect_pad4_led,1) # Tempo mode - turn light on } var.set[$deck_a_slider_index=1] { avPitchSet(A,0.0,F2|F6) # init sync with last tempo slider position BlinkSet(~deck_a_effect_pad4_led,0) # Pitch mode - turn light off } av[SliderRangeNew.Tempo,A] { ($deck_a_slider_index=0) avTempoSet(A,0.0,F2|F6) # init sync with last tempo slider position } av[SliderRangeNew.Pitch,A] { ($deck_a_slider_index=1) avPitchSet(A,0.0,F2|F7) # init sync with last pitch slider position } ####### Deck B: Slider midi.absval[S,0xB0:0x35,0x7F,0x40,0x00] SubCall(@deck_b_slider_val) sub[@deck_b_slider_val] { # new value from slider ($deck_b_slider_index=0) SubCall(@deck_b_slider_val_tempo) ($deck_b_slider_index=1) SubCall(@deck_b_slider_val_pitch) } sub[@deck_b_slider_val_tempo] { # slider pos -- tempo ($global_shift=0) avTempoSet(B,_) # normal sync logic ($global_shift=1) avTempoSet(B,_,F1) # force synced state } sub[@deck_b_slider_val_pitch] { # slider pos -- pitch ($global_shift=0) avPitchSet(B,_) # normal sync logic ($global_shift=1) avPitchSet(B,_,F1) # force synced state } var.set[$deck_b_slider_index=0] { avTempoSet(B,0.0,F2|F7) # init sync with last pitch slider position BlinkSet(~deck_b_effect_pad4_led,1) # Tempo mode - turn light on } var.set[$deck_b_slider_index=1] { avPitchSet(B,0.0,F2|F6) # init sync with last tempo slider position BlinkSet(~deck_b_effect_pad4_led,0) # Pitch mode - turn light off } av[SliderRangeNew.Tempo,B] { ($deck_b_slider_index=0) avTempoSet(B,0.0,F2|F6) # init sync with last tempo slider position } av[SliderRangeNew.Pitch,B] { ($deck_b_slider_index=1) avPitchSet(B,0.0,F2|F7) # init sync with last pitch slider position } ######################################################## ####### Playlist Navigation midi.trigger[0x90:0x36:0x7F] avPlaylistNav(T) # Left button pressed midi.trigger[0x90:0x35:0x7F] avPlaylistNav(T) # Right button pressed midi.trigger[0x90:0x34:0x7F] SubCall(@playlist_down_pressed) # Down button pressed sub[@playlist_down_pressed] { avPlaylistNav.Walk(+1) VarSet($playlist_down_button_count,1) } midi.trigger[0x90:0x34:0x00] SubCall(@playlist_down_released) # Down button released sub[@playlist_down_released] VarSet($playlist_down_button_count,0) midi.trigger[0x90:0x33:0x7F] SubCall(@playlist_up_pressed) # Up button pressed sub[@playlist_up_pressed] { avPlaylistNav.Walk(-1) VarSet($playlist_up_button_count,1) } midi.trigger[0x90:0x33:0x00] SubCall(@playlist_up_released) # Up button released sub[@playlist_up_released] VarSet($playlist_up_button_count,0) var.set[$playlist_down_button_count=7] { # Down button held count avPlaylistNav.Walk(+3) VarSet($playlist_down_button_count,6) } var.set[$playlist_up_button_count=7] { # Up button held count avPlaylistNav.Walk(-3) VarSet($playlist_up_button_count,6) } timer.tick ($playlist_down_button_count!=0) VarInc($playlist_down_button_count) timer.tick ($playlist_up_button_count!=0) VarInc($playlist_up_button_count) midi.trigger[0x90:0x15:0x7F] ($deck_a_playing=0) Subcall(@deck_a_playlist_loadnext) sub[@deck_a_playlist_loadnext] { # load next item from playlist ($global_shift=0) avPlaylistNav.Load(A,F1) # Load selected item ($global_shift=1) avLoadNext(A,F1) # Load next item } midi.trigger[0x90:0x2B:0x7F] ($deck_b_playing=0) Subcall(@deck_b_playlist_loadnext) sub[@deck_b_playlist_loadnext] { # load next item from playlist ($global_shift=0) avPlaylistNav.Load(B,F1) # Load selected item ($global_shift=1) avLoadNext(B,F1) # Load next item } av[PlaylistNav,D] { avPlaylistNav(T) } ######################################################## ####### Deck A: Looping functionality midi.trigger[0x90:0x09:0x20,0xFF:0xFF:0x20] { # Loop1 deck A pad down (MIDI codes type 1) (midi.trigger with mask to capture upper 3/4 range) ($deck_a_loop_pad1_down=0) Subcall(@deck_a_try_loop1_press) # only execute if pad not been down already VarSet($deck_a_loop_pad1_down,1) } midi.trigger[0xA0:0x09:0x20,0xFF:0xFF:0x20] { # Loop1 deck A pad down (MIDI codes type 2) (midi.trigger with mask to capture upper 3/4 range) ($deck_a_loop_pad1_down=0) Subcall(@deck_a_try_loop1_press) # only execute if pad not been down already VarSet($deck_a_loop_pad1_down,1) } midi.trigger[0x90:0x09:0x00] { # Loop1 deck A pad up VarSet($deck_a_loop_pad1_down,0) } sub[@deck_a_try_loop1_press] ($deck_a_loaded=1) Subcall(@deck_a_try_loop1_press2) # only execute if deck A loaded sub[@deck_a_try_loop1_press2] { # Execute function based on current loop1 state (state 0: out of loop, 1: setting loop, 2: looping) ($deck_a_loop2_state!=0) avLooping.CancelAll(A,F0) # if loop2 active cancel ($deck_a_loop2_state!=0) VarSet($deck_a_loop2_state,0) # if loop2 active cancel and reset loop state ($deck_a_loop1_state=0) Subcall(@deck_a_loop1_state0) ($deck_a_loop1_state=1) Subcall(@deck_a_loop1_state1) ($deck_a_loop1_state=2) avLooping.CancelAll(A,F0) # exit loop ($deck_a_loop1_entered=0) VarIncWrap($deck_a_loop1_state) ($deck_a_loop1_entered=1) VarSet($deck_a_loop1_state,2) # set to state 2: looping ($deck_a_loop1_entered=1) VarSet($deck_a_loop1_entered,0) # reset loop entered variable } sub[@deck_a_loop1_state0] { # Execute function based on shift state ($global_shift=0) avLooping.MarkA.1(A) # mark loop start ($global_shift=1) avLooping.EnterLoop.1(A) # enter loop ($global_shift=1) VarSet($deck_a_loop1_entered,1) } sub[@deck_a_loop1_state1] { # Execute function based on shift state ($global_shift=0) avLooping.MarkB(A) # mark loop end ($global_shift=1) avLooping.MarkB(A,F0) # suppress beat-snapping } var.set[$deck_a_loop1_state=0] { # Loop exit state - turn LED off BlinkSet(~deck_a_loop_pad1_led,0) } var.set[$deck_a_loop1_state=1] { # Loop setting state - turn LED fast blink BlinkSet(~deck_a_loop_pad1_led,4) } var.set[$deck_a_loop1_state=2] { # Loop looping state - turn LED on BlinkSet(~deck_a_loop_pad1_led,1) } midi.trigger[0x90:0x0A:0x20,0xFF:0xFF:0x20] { # Loop2 deck A pad down (MIDI codes type 1) (midi.trigger with mask to capture upper 3/4 range) ($deck_a_loop_pad2_down=0) Subcall(@deck_a_try_loop2_press) # only execute if pad not been down already VarSet($deck_a_loop_pad2_down,1) } midi.trigger[0xA0:0x0A:0x20,0xFF:0xFF:0x20] { # Loop2 deck A pad down (MIDI codes type 2) (midi.trigger with mask to capture upper 3/4 range) ($deck_a_loop_pad2_down=0) Subcall(@deck_a_try_loop2_press) # only execute if pad not been down already VarSet($deck_a_loop_pad2_down,1) } midi.trigger[0x90:0x0A:0x00] { # Loop2 deck A pad up VarSet($deck_a_loop_pad2_down,0) } sub[@deck_a_try_loop2_press] ($deck_a_loaded=1) Subcall(@deck_a_try_loop2_press2) # only execute if deck A loaded sub[@deck_a_try_loop2_press2] { # Execute function based on current loop2 state (state 0: out of loop, 1: setting loop, 2: looping) ($deck_a_loop1_state!=0) avLooping.CancelAll(A,F0) # if loop1 active cancel ($deck_a_loop1_state!=0) VarSet($deck_a_loop1_state,0) # if loop1 active cancel and reset loop state ($deck_a_loop2_state=0) Subcall(@deck_a_loop2_state0) ($deck_a_loop2_state=1) Subcall(@deck_a_loop2_state1) ($deck_a_loop2_state=2) avLooping.CancelAll(A,F0) # exit loop ($deck_a_loop2_entered=0) VarIncWrap($deck_a_loop2_state) ($deck_a_loop2_entered=1) VarSet($deck_a_loop2_state,2) # set to state 2: looping ($deck_a_loop2_entered=1) VarSet($deck_a_loop2_entered,0) # reset loop entered variable } sub[@deck_a_loop2_state0] { # Execute function based on shift state ($global_shift=0) avLooping.MarkA.2(A) # mark loop start ($global_shift=1) avLooping.EnterLoop.2(A) # enter loop ($global_shift=1) VarSet($deck_a_loop2_entered,1) } sub[@deck_a_loop2_state1] { # Execute function based on shift state ($global_shift=0) avLooping.MarkB(A) # mark loop end ($global_shift=1) avLooping.MarkB(A,F0) # suppress beat-snapping } var.set[$deck_a_loop2_state=0] { # Loop exit state - turn LED off BlinkSet(~deck_a_loop_pad2_led,0) } var.set[$deck_a_loop2_state=1] { # Loop setting state - turn LED fast blink BlinkSet(~deck_a_loop_pad2_led,4) } var.set[$deck_a_loop2_state=2] { # Loop looping state - turn LED on BlinkSet(~deck_a_loop_pad2_led,1) } midi.trigger[0x90:0x0B:0x20,0xFF:0xFF:0x20] { # Loop Length pad down (MIDI codes type 1) (midi.trigger with mask to capture upper 3/4 range) ($deck_a_loop_pad3_down=0) Subcall(@deck_a_try_length_press) # only execute if pad not been down already VarSet($deck_a_loop_pad3_down,1) } midi.trigger[0xA0:0x0B:0x20,0xFF:0xFF:0x20] { # Loop Length pad down (MIDI codes type 2) (midi.trigger with mask to capture upper 3/4 range) ($deck_a_loop_pad3_down=0) Subcall(@deck_a_try_length_press) # only execute if pad not been down already VarSet($deck_a_loop_pad3_down,1) } midi.trigger[0x90:0x0B:0x00] { # Loop Length pad up VarSet($deck_a_loop_pad3_down,0) } sub[@deck_a_try_length_press] ($deck_a_loaded=1) Subcall(@deck_a_try_length_press2) # only execute if deck A loaded sub[@deck_a_try_length_press2] { # Only cancel setting loop supported in this version (Length not supported) ($deck_a_loop1_state=1) avLooping.CancelAll(A,F0) # cancel setting loop ($deck_a_loop1_state=1) VarSet($deck_a_loop1_state,0) # reset loop state ($deck_a_loop2_state=1) avLooping.CancelAll(A,F0) # cancel setting loop ($deck_a_loop2_state=1) VarSet($deck_a_loop2_state,0) # reset loop state } var.set[$deck_a_loop_pad3_down=1] { # Loop Length pad down - turn LED on ($deck_a_loaded=1) BlinkSet(~deck_a_loop_pad3_led,1) } var.set[$deck_a_loop_pad3_down=0] { # Loop Length pad up - turn LED off BlinkSet(~deck_a_loop_pad3_led,0) } midi.trigger[0x90:0x0C:0x20,0xFF:0xFF:0x20] { # Tap A pad down (MIDI codes type 1) (midi.trigger with mask to capture upper 3/4 range) ($deck_a_loop_pad4_down=0) avTapBPM(A) # send beat trigger for BPM detection - only execute if pad not been down already VarSet($deck_a_loop_pad4_down,1) } midi.trigger[0xA0:0x0C:0x20,0xFF:0xFF:0x20] { # Tap A pad down (MIDI codes type 2) (midi.trigger with mask to capture upper 3/4 range) ($deck_a_loop_pad4_down=0) avTapBPM(A) # send beat trigger for BPM detection - only execute if pad not been down already VarSet($deck_a_loop_pad4_down,1) } midi.trigger[0x90:0x0C:0x00] { # Tap A pad up VarSet($deck_a_loop_pad4_down,0) } var.set[$deck_a_loop_pad4_down=1] { # Tap A pad down - turn LED on ($deck_a_loaded=1) BlinkSet(~deck_a_loop_pad4_led,1) } var.set[$deck_a_loop_pad4_down=0] { # Tap A pad up - turn LED off BlinkSet(~deck_a_loop_pad4_led,0) } var.set[$deck_a_loaded=0] { # deck A ejected - init looping state variables VarSet($deck_a_loop1_state,0) VarSet($deck_a_loop2_state,0) } ####### Deck B: Looping functionality midi.trigger[0x90:0x1F:0x20,0xFF:0xFF:0x20] { # Loop1 deck B pad down (MIDI codes type 1) (midi.trigger with mask to capture upper 3/4 range) ($deck_b_loop_pad1_down=0) Subcall(@deck_b_try_loop1_press) # only execute if pad not been down already VarSet($deck_b_loop_pad1_down,1) } midi.trigger[0xA0:0x1F:0x20,0xFF:0xFF:0x20] { # Loop1 deck B pad down (MIDI codes type 2) (midi.trigger with mask to capture upper 3/4 range) ($deck_b_loop_pad1_down=0) Subcall(@deck_b_try_loop1_press) # only execute if pad not been down already VarSet($deck_b_loop_pad1_down,1) } midi.trigger[0x90:0x1F:0x00] { # Loop1 deck B pad up VarSet($deck_b_loop_pad1_down,0) } sub[@deck_b_try_loop1_press] ($deck_b_loaded=1) Subcall(@deck_b_try_loop1_press2) # only execute if Deck B loaded sub[@deck_b_try_loop1_press2] { # Execute function based on current loop1 state (state 0: out of loop, 1: setting loop, 2: looping) ($deck_b_loop2_state!=0) avLooping.CancelAll(B,F0) # if loop2 active cancel ($deck_b_loop2_state!=0) VarSet($deck_b_loop2_state,0) # if loop2 active cancel and reset loop state ($deck_b_loop1_state=0) Subcall(@deck_b_loop1_state0) ($deck_b_loop1_state=1) Subcall(@deck_b_loop1_state1) ($deck_b_loop1_state=2) avLooping.CancelAll(B,F0) # exit loop ($deck_b_loop1_entered=0) VarIncWrap($deck_b_loop1_state) ($deck_b_loop1_entered=1) VarSet($deck_b_loop1_state,2) # set to state 2: looping ($deck_b_loop1_entered=1) VarSet($deck_b_loop1_entered,0) # reset loop entered variable } sub[@deck_b_loop1_state0] { # Execute function based on shift state ($global_shift=0) avLooping.MarkA.1(B) # mark loop start ($global_shift=1) avLooping.EnterLoop.1(B) # enter loop ($global_shift=1) VarSet($deck_b_loop1_entered,1) } sub[@deck_b_loop1_state1] { # Execute function based on shift state ($global_shift=0) avLooping.MarkB(B) # mark loop end ($global_shift=1) avLooping.MarkB(B,F0) # suppress beat-snapping } var.set[$deck_b_loop1_state=0] { # Loop exit state - turn LED off BlinkSet(~deck_b_loop_pad1_led,0) } var.set[$deck_b_loop1_state=1] { # Loop setting state - turn LED fast blink BlinkSet(~deck_b_loop_pad1_led,4) } var.set[$deck_b_loop1_state=2] { # Loop looping state - turn LED on BlinkSet(~deck_b_loop_pad1_led,1) } midi.trigger[0x90:0x20:0x20,0xFF:0xFF:0x20] { # Loop2 deck B pad down (MIDI codes type 1) (midi.trigger with mask to capture upper 3/4 range) ($deck_b_loop_pad2_down=0) Subcall(@deck_b_try_loop2_press) # only execute if pad not been down already VarSet($deck_b_loop_pad2_down,1) } midi.trigger[0xA0:0x20:0x20,0xFF:0xFF:0x20] { # Loop2 deck B pad down (MIDI codes type 2) (midi.trigger with mask to capture upper 3/4 range) ($deck_b_loop_pad2_down=0) Subcall(@deck_b_try_loop2_press) # only execute if pad not been down already VarSet($deck_b_loop_pad2_down,1) } midi.trigger[0x90:0x20:0x00] { # Loop2 deck B pad up VarSet($deck_b_loop_pad2_down,0) } sub[@deck_b_try_loop2_press] ($deck_b_loaded=1) Subcall(@deck_b_try_loop2_press2) # only execute if Deck B loaded sub[@deck_b_try_loop2_press2] { # Execute function based on current loop2 state (state 0: out of loop, 1: setting loop, 2: looping) ($deck_b_loop1_state!=0) avLooping.CancelAll(B,F0) # if loop1 active cancel ($deck_b_loop1_state!=0) VarSet($deck_b_loop1_state,0) # if loop1 active cancel and reset loop state ($deck_b_loop2_state=0) Subcall(@deck_b_loop2_state0) ($deck_b_loop2_state=1) Subcall(@deck_b_loop2_state1) ($deck_b_loop2_state=2) avLooping.CancelAll(B,F0) # exit loop ($deck_b_loop2_entered=0) VarIncWrap($deck_b_loop2_state) ($deck_b_loop2_entered=1) VarSet($deck_b_loop2_state,2) # set to state 2: looping ($deck_b_loop2_entered=1) VarSet($deck_b_loop2_entered,0) # reset loop entered variable } sub[@deck_b_loop2_state0] { # Execute function based on shift state ($global_shift=0) avLooping.MarkA.2(B) # mark loop start ($global_shift=1) avLooping.EnterLoop.2(B) # enter loop ($global_shift=1) VarSet($deck_b_loop2_entered,1) } sub[@deck_b_loop2_state1] { # Execute function based on shift state ($global_shift=0) avLooping.MarkB(B) # mark loop end ($global_shift=1) avLooping.MarkB(B,F0) # suppress beat-snapping } var.set[$deck_b_loop2_state=0] { # Loop exit state - turn LED off BlinkSet(~deck_b_loop_pad2_led,0) } var.set[$deck_b_loop2_state=1] { # Loop setting state - turn LED fast blink BlinkSet(~deck_b_loop_pad2_led,4) } var.set[$deck_b_loop2_state=2] { # Loop looping state - turn LED on BlinkSet(~deck_b_loop_pad2_led,1) } midi.trigger[0x90:0x21:0x20,0xFF:0xFF:0x20] { # Loop Length pad down (MIDI codes type 1) (midi.trigger with mask to capture upper 3/4 range) ($deck_b_loop_pad3_down=0) Subcall(@deck_b_try_length_press) # only execute if pad not been down already VarSet($deck_b_loop_pad3_down,1) } midi.trigger[0xA0:0x21:0x20,0xFF:0xFF:0x20] { # Loop Length pad down (MIDI codes type 2) (midi.trigger with mask to capture upper 3/4 range) ($deck_b_loop_pad3_down=0) Subcall(@deck_b_try_length_press) # only execute if pad not been down already VarSet($deck_b_loop_pad3_down,1) } midi.trigger[0x90:0x21:0x00] { # Loop Length pad up VarSet($deck_b_loop_pad3_down,0) } sub[@deck_b_try_length_press] ($deck_b_loaded=1) Subcall(@deck_b_try_length_press2) # only execute if Deck B loaded sub[@deck_b_try_length_press2] { # Only cancel setting loop supported in this version (Length not supported) ($deck_b_loop1_state=1) avLooping.CancelAll(B,F0) # cancel setting loop ($deck_b_loop1_state=1) VarSet($deck_b_loop1_state,0) # reset loop state ($deck_b_loop2_state=1) avLooping.CancelAll(B,F0) # cancel setting loop ($deck_b_loop2_state=1) VarSet($deck_b_loop2_state,0) # reset loop state } var.set[$deck_b_loop_pad3_down=1] { # Loop Length pad down - turn LED on ($deck_b_loaded=1) BlinkSet(~deck_b_loop_pad3_led,1) } var.set[$deck_b_loop_pad3_down=0] { # Loop Length pad up - turn LED off BlinkSet(~deck_b_loop_pad3_led,0) } midi.trigger[0x90:0x22:0x20,0xFF:0xFF:0x20] { # Tap B pad down (MIDI codes type 1) (midi.trigger with mask to capture upper 3/4 range) ($deck_b_loop_pad4_down=0) avTapBPM(B) # send beat trigger for BPM detection - only execute if pad not been down already VarSet($deck_b_loop_pad4_down,1) } midi.trigger[0xA0:0x22:0x20,0xFF:0xFF:0x20] { # Tap B pad down (MIDI codes type 2) (midi.trigger with mask to capture upper 3/4 range) ($deck_b_loop_pad4_down=0) avTapBPM(B) # send beat trigger for BPM detection - only execute if pad not been down already VarSet($deck_b_loop_pad4_down,1) } midi.trigger[0x90:0x22:0x00] { # Tap B pad up VarSet($deck_b_loop_pad4_down,0) } var.set[$deck_b_loop_pad4_down=1] { # Tap B pad down - turn LED on ($deck_b_loaded=1) BlinkSet(~deck_b_loop_pad4_led,1) } var.set[$deck_b_loop_pad4_down=0] { # Tap B pad up - turn LED off BlinkSet(~deck_b_loop_pad4_led,0) } var.set[$deck_b_loaded=0] { # Deck B ejected - init looping state variables VarSet($deck_b_loop1_state,0) VarSet($deck_b_loop2_state,0) }